//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2003 Intrinsyc Europe Ltd.
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004 Siemens AG
//
// Version: 1.1.2.5
// Date:    11. Jan. 2006
//////////////////////////////////////////////////////////////////////////////
//
//
// (C) Copyright 2007 Marvell International Ltd.
//  All Rights Reserved
//


#pragma once

//
// Forward declarations
//
class CRilInstanceHandle;
class CNotificationData;
enum APIID;

// Default API execution time (in msec)
#define EXECTIME_API_DEFAULT        25

//
// Command options
//
#define CMDOPT_NONE                     0x00000000
#define CMDOPT_IGNORERSP                0x00000001
#define CMDOPT_INIT                     0x00000002
#define CMDOPT_REINIT                   0x00000004
#define CMDOPT_HANGUP                   0x00000008
#define CMDOPT_DIAL                     0x00000010
#define CMDOPT_ANSWER                   0x00000020
#define CMDOPT_GENERALINIT              0x00000040
#define CMDOPT_URC                      0x00000080
#define CMDOPT_NOOP                     0x00000100
#define CMDOPT_POWER                    0x00000200
#define CMDOPT_FINALINIT                0x00000400
#define CMDOPT_RETRYONSIMLOCKED         0x00000800
#define CMDOPT_IGNORERADIOOFF           0x00001000
#define CMDOPT_SETRADIOON               0x00002000
#define CMDOPT_SIMQUERY                 0x00004000
#define CMDOPT_DELAYCONNECTRSP          0x00008000
#define CMDOPT_LONGDIALSTRING           0x00010000
#define CMDOPT_SUPPRESSLOGGING          0x00020000
#define CMDOPT_UNLOCKING                0x00040000
#define CMDOPT_POLLING                  0x00080000
#define CMDOPT_CPIN2RELATED             0x00100000
#define CMDOPT_CPIN2NEUTRAL             0x00200000
#define CMDOPT_INTERMEDIATERESPONSE     0x00400000
#define CMDOPT_SMSACK                   0x00800000
#define CMDOPT_KEEPORDER                0x01000000
#define CMDOPT_REQUIRECONNECTRSP        0x02000000

//
// Command priorities
//
#define CMDPRI_CRITICAL                 0
#define CMDPRI_HIGHEST                  1
#define CMDPRI_HIGH                     2
#define CMDPRI_NORMAL                   3
#define CMDPRI_LOW                      4

//
// Parsing callback stored in CCommand
//
typedef HRESULT (*PFN_CMD_PARSE)(LPCSTR szRsp, void*& pBlob, UINT& cbBlob, LPVOID pParam);
typedef HRESULT (*PFN_CMD_ERROR)(LPCSTR szRsp, LPVOID pParam);
typedef HRESULT (*PFN_PRE_CMD_CHECK)(CRilHandle *, COM_PORT_TYPE);


struct CME_TRANSLATION {
  HRESULT hrModuleErrorCode;
  HRESULT hrMicrosoftErrorCode;
};


//
// AT command
//
class CCommand : public CListElem
{
public:
                          CCommand();
                          ~CCommand();

  BOOL                    Init(CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const LPCSTR szCmdPart2, const DWORD dwOptions,
                               const DWORD dwTimeout, CNotificationData* const pnd, const PFN_CMD_PARSE pfnParse,
                               const DWORD dwRetriesOnError, const DWORD dwRetryOnErrorDelay, const APIID apiid,
                               const PFN_CMD_ERROR pfnError = NULL, const LPVOID pParseParam = NULL, const CME_TRANSLATION *pCMET = NULL,
                               PFN_PRE_CMD_CHECK   pfnPreCheck = NULL);
  BOOL                    Init(CCommand* pCmd, BOOL bClone);
  void                    SendResponse(const DWORD dwResponseCode, const void* const pBlob, const UINT cbBlob) const;
  CRilInstanceHandle*     GetHandle() const           { return m_pHandle; };
  LPSTR                   GetCmd() const              { return m_szCmd; };
  LPSTR                   GetCmdPart2() const         { return m_szCmdPart2; };
  const CME_TRANSLATION*  GetCMET()                   { return m_pCMET; };
  HRESULT                 GetID() const               { return m_hrCmdID; };
  void                    ClearHandle()               { m_pHandle = NULL; };
  BOOL                    FIgnoreRsp() const          { return (m_dwOptions & CMDOPT_IGNORERSP); };
  BOOL                    FInit() const               { return (m_dwOptions & CMDOPT_INIT); };
  BOOL                    FReinit() const             { return (m_dwOptions & CMDOPT_REINIT); };
  BOOL                    FHangup() const             { return (m_dwOptions & CMDOPT_HANGUP); };
  BOOL                    FDial() const               { return (m_dwOptions & CMDOPT_DIAL); };
  BOOL                    FAnswer() const             { return (m_dwOptions & CMDOPT_ANSWER); };
  BOOL                    FGeneralInit() const        { return (m_dwOptions & CMDOPT_GENERALINIT); };
  BOOL                    FFinalInit() const          { return (m_dwOptions & CMDOPT_FINALINIT); };
  BOOL                    FNoOp() const               { return (m_dwOptions & CMDOPT_NOOP); };
  BOOL                    IsSMSAck() const            { return (m_dwOptions & CMDOPT_SMSACK); };
  BOOL                    FPower() const              { return (m_dwOptions & CMDOPT_POWER); };
  BOOL                    FUrc() const                { return (m_dwOptions & CMDOPT_URC); };
  BOOL                    FKeepOrder() const          { return (m_dwOptions & CMDOPT_KEEPORDER); };
  BOOL                    FRequireConnectRsp() const  { return (m_dwOptions & CMDOPT_REQUIRECONNECTRSP); };
  BOOL                    CmdOptIsSet(DWORD Flag)     { return (m_dwOptions & Flag); }
  void                    SetCmdOpt(DWORD Flag)       { m_dwOptions |= Flag; }
  void                    ClrCmdOpt(DWORD Flag)       { m_dwOptions &= ~Flag; }
  DWORD                   GetTimeout() const          { return m_dwTimeout; };
  CNotificationData*      GiveUpNotificationData()    { CNotificationData* pnd = m_pndNotify; m_pndNotify = NULL; return pnd; };
  PFN_CMD_PARSE           GetParseFunc() const        { return m_pfnParse; };
  PFN_CMD_ERROR           GetErrorFunc() const        { return m_pfnError; };
  PFN_PRE_CMD_CHECK       GetPreCheckFunc() const     { return m_pfnPreCheck; };
  LPVOID                  GetParseParam() const       { return m_pParseParam; };
  DWORD                   GetPriority() const;
  APIID                   GetAPIID() const            { return m_apiid; };
  BOOL                    RetryCommandOnError(COM_PORT_TYPE PortType);
  DWORD                   GetExecTime() const         { return m_dwExecTime; };
  void                    Age()                       { m_dwExecTime /= 2; };

private:
  LPSTR                   m_szCmd;
  LPSTR                   m_szCmdPart2;
  const CME_TRANSLATION*  m_pCMET;
  HRESULT                 m_hrCmdID;
  DWORD                   m_dwTimeout;
  CNotificationData*      m_pndNotify;
  PFN_CMD_PARSE           m_pfnParse;
  PFN_CMD_ERROR           m_pfnError;
  PFN_PRE_CMD_CHECK       m_pfnPreCheck;
  LPVOID                  m_pParseParam;
  DWORD                   m_dwRetriesOnError;
  DWORD                   m_dwRetryOnErrorDelay;
  APIID                   m_apiid;

protected:
  CRilInstanceHandle*     m_pHandle;
  DWORD                   m_dwOptions;
  DWORD                   m_dwExecTime;
};

